﻿// Inner Kit 库
// 总头文件
// Copyright (c) 2024 by 尔西大帝. All rights reserved.
//
// 这个文件包括所有工具的连接。使用时连接此文件即可。
//
// Author: 尔西大帝
// Email: 2670613871@qq.com
// Created: 2024-12-01

#include "image.h"
#include "kits.h"
#include <klog.h>

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

namespace ikit {
static void CopyRgbToRgba(
    unsigned char* dest, unsigned char* src, int width, int height) {
  // 将RGB数据复制到RGBA缓冲区，并设置Alpha值为255
  for (int i = 0; i < height; ++i) {
    for (int j = 0; j < width; ++j) {
      dest[0] = src[0]; // R
      dest[1] = src[1]; // G
      dest[2] = src[2]; // B
      dest[3] = 255;
      dest += 4;
      src += 3;
    }
  }
}

static void CopyRgbToRgbaNormal(
    unsigned char* dest, unsigned char* src, int width, int height) {
  // 将RGB数据复制到RGBA缓冲区，并设置Alpha值为255
  for (int i = 0; i < height; ++i) {
    for (int j = 0; j < width; ++j) {
      dest[0] = src[0]; // R
      dest[1] = src[1]; // G
      dest[2] = src[2]; // B
      dest[3] = 255;
      dest += 4;
      src += 3;
    }
  }
}

ImageData::ImageData() : width(0), height(0), channels(0), data(nullptr) {}
ImageData::ImageData(const std::wstring& path, bool is_flip)
    : width(0), height(0), channels(0), data(nullptr) {
  Load(path, is_flip);
}

unsigned char* ImageData::Load(const std::wstring& path, bool is_flip) {
  // 因为有些纹理是从下而上的，所以要反转
  stbi_set_flip_vertically_on_load(is_flip);
  //// 使用Stbi载入文件
  // data = stbi_load(filename, &width, &height, &channels, 0);

  // 使用_wfopen打开文件（支持宽字符路径）
  FILE* file = _wfopen(path.c_str(), L"rb");
  if (!file) {
    KLOG("Failed to open file: %s", path.c_str());
    return nullptr;
  }

  // 使用stbi_load_from_file加载图片
  data = stbi_load_from_file(file, &width, &height, &channels, 0);

  return data;
}

void ImageData::ConvertToChannels4(bool is_normal) {
  if (channels == 3) {
    // 分配新的内存，并且进行复制
    unsigned int dstDepthPitch = width * height * 4;
    unsigned char* rgba_data = (unsigned char*)STBI_MALLOC(dstDepthPitch);
    if (is_normal) {
      CopyRgbToRgbaNormal(rgba_data, data, width, height);
    } else {
      CopyRgbToRgba(rgba_data, data, width, height);
    }

    // 删除原来的项目，并且进行替换
    Release();
    data = rgba_data;
    channels = 4;
  }
}

void ImageData::Release() {
  if (data != nullptr) {
    STBI_FREE(data);
    data = nullptr;
  }
}

ImageData load_image(const std::wstring& filename, bool is_flip) {
  return ImageData(filename, is_flip);
}

} // namespace ikit
